import { init } from 'echarts'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
//引入物理属性的库
import {OimoPhysics} from 'three/examples/jsm/physics/OimoPhysics'

let renderer, camera, scene
let axesHelper
let floor, boxes,spheres
let hesLight,dirLight
let controls
let physics
let position = new THREE.Vector3();






initRenderer()
initCamera()
initScene()
initLight()
initMeshes()
initAxesHelper()
initControls()
enableShadow()
enablePhysics()
animate()


window.addEventListener('resize', function () {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
})


function initRenderer() {
    renderer = new THREE.WebGLRenderer()
    renderer.setPixelRatio(window.devicePixelRatio)
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.outputEncoding = THREE.sRGBEncoding
    document.body.appendChild(renderer.domElement)
}

function initCamera() {
    camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000)
    camera.position.set(4,4,4)
}

function initScene(params) {
    scene = new THREE.Scene()
    scene.background = new THREE.Color(0x888888)
}

function initAxesHelper(params) {
    axesHelper = new THREE.AxesHelper(3)
    scene.add(axesHelper)
}

function initLight(params) {
    //环境光
    hesLight = new THREE.HemisphereLight() //白色光
    hesLight.intensity = 0.3
    scene.add(hesLight)

    //平行光  太阳光
    dirLight = new THREE.DirectionalLight()
    dirLight.position.set(5, 5, -5)
    scene.add(dirLight)
}
function initMeshes(params) {
  //地面
    floor = new THREE.Mesh(
        new THREE.BoxGeometry(10, 1, 10),
        new THREE.ShadowMaterial({color:0x111111})
    )
    floor.position.set(0,-1,0)
    scene.add(floor)

    //boxes
    boxes = new THREE.InstancedMesh(
        new THREE.BoxGeometry(0.1, 0.1, 0.1),
        new THREE.MeshBasicMaterial(), 100  //如木头,镜面反色差
    
    );
    const matrix = new THREE.Matrix4();
    const color = new THREE.Color()
    for (let i = 0; i < boxes.count; i++) { 
        matrix.setPosition(
            Math.random() - 0.5,    // x:-0.5`0.5
            Math.random() * 2 ,  // y:0`2
            Math.random() - 0.5 , // x:-0.5`0.5
            
        );
        boxes.setMatrixAt(i, matrix)
        boxes.setColorAt(i, color.setHex(Math.random() * 0xffffff))
    }
    scene.add(boxes)

     //spheres
     spheres = new THREE.InstancedMesh(
        new THREE.IcosahedronGeometry(0.075,3),
        new THREE.MeshLambertMaterial(), 100  //如木头,镜面反色差
    
    );
 
    for (let i = 0; i < spheres.count; i++) { 
        matrix.setPosition(
            Math.random() - 0.5,    // x:-0.5`0.5
            Math.random() * 2 ,  // y:0`2
            Math.random() - 0.5 , // x:-0.5`0.5
            
        );
        spheres.setMatrixAt(i, matrix)
        spheres.setColorAt(i, color.setHex(Math.random() * 0xffffff))
    }
    scene.add(spheres)
}
function enableShadow(params) {
    renderer.shadowMap.enabled = true;
    dirLight.castShadow = true;
    floor.receiveShadow = true;
    boxes.castShadow = true;
    boxes.receiveShadow = true;
}
async function enablePhysics(params) {
    physics = await OimoPhysics()
    physics.addMesh(floor)
    physics.addMesh(boxes, 1)
    physics.addMesh(spheres,1)
}

function  initControls(params) {
    controls = new OrbitControls(camera, renderer.domElement)
    controls.target.y = 1
    controls.update()
}

function animate(params) {
    requestAnimationFrame(animate)
    let index = Math.floor(Math.random() * boxes.count);
    position.set(0, Math.random() + 1, 0)
    physics.setMeshPosition(boxes, position, index)

     index = Math.floor(Math.random() * boxes.count);
    position.set(0, Math.random() + 1, 0)
    physics.setMeshPosition(spheres, position, index)
    
    renderer.render(scene, camera)
    // console.log(new Date().getMilliseconds());
}

